package bizlogic;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import model.BookingDTO;
import model.PriorityDTO;
import model.search.BookingSearchDTO;

import dao.BookingDAO;
import dao.DAOException;
import dao.DAOFactory;

public class BookingManager {
	
	private BookingDAO bookDAO;
	
	public BookingManager()
	{
		bookDAO = DAOFactory.loadInstance().getBookingDAO();
	}
	
	public ArrayList<BookingDTO> findBookingByCriteria(BookingSearchDTO bs) {
		ArrayList<BookingDTO> list = new ArrayList<BookingDTO>();
		
		try {
			list = bookDAO.findBookingByCriteria(bs);
		} catch (DAOException e) {
			e.printStackTrace();
		}
		
		return list;
	}
	
	public BookingDTO getBooking(String id) {
		BookingDTO data = null;
		
		try {
			data = bookDAO.getBooking(id);
		} catch (DAOException e) {
			e.printStackTrace();
		}
		
		return data;
	}
	
	public ArrayList<BookingDTO> getAll() {
		ArrayList<BookingDTO> list = new ArrayList<BookingDTO>();
	
		try {
			list = bookDAO.getAll();
		} catch (DAOException e) {
			e.printStackTrace();
		}
		
		return list;
	}
	
	public String insertBooking(BookingDTO data) {
		String error = "";
		
		try {
			if ( data.getId() == null || data.getId().equalsIgnoreCase("") ) {
				data.setId(bookDAO.generateNumber());
			}
			
			Calendar c = Calendar.getInstance();
			c.setTime(data.getStartDate());
			
			if ( data.getEndDate().before(data.getStartDate()) ) {
				error = "End Data must be after Start Date!";
			} else if ( !isValidHighPriority(data.getUserId(), data.getPriority(), c.get(Calendar.YEAR), c.get(Calendar.MONTH) )) {
				error = "Maximum 3 Highest Priority at a particular month!";
			} else if ( isBookingOverlap(data.getFacilityName(), data.getStartDate(), data.getEndDate() ) ) {
				error = "Facility " + data.getFacilityName() + " is not available on particular date!";
			} else if ( isUserOverlap(data.getUserId(), data.getStartDate(), data.getEndDate()) ) {
				error = "User already book another facility on particular date!";
			} else {
				bookDAO.insertBooking(data);
			}
			
		} catch (DAOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return error;
	}
	
	public String updateBooking(BookingDTO data) {
		String error = "";
		
		try {
			Calendar c = Calendar.getInstance();
			c.setTime(data.getStartDate());
			
//			if ( data.getEndDate().before(data.getStartDate()) ) {
//				error = "End Data must be after Start Date!";
//			} else if ( !isValidHighPriority(data.getUserId(), data.getPriority(), c.get(Calendar.YEAR), c.get(Calendar.MONTH) )) {
//				error = "Maximum 3 Highest Priority at a particular month!";
//			} else if ( isBookingOverlap(data.getFacilityName(), data.getStartDate(), data.getEndDate() ) ) {
//				error = "Facility " + data.getFacilityName() + " is not available on particular date and time!";
//			} else if ( isUserOverlap(data.getUserId(), data.getStartDate(), data.getEndDate()) ) {
//				error = "User already book another facility on particular date!";
//			} else {
//				bookDAO.updateBooking(data);
//			}
			bookDAO.updateBooking(data);
			
		} catch (DAOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return error;
	}
	
	public boolean isValidHighPriority(String userId, int priority, int year, int month) {
		boolean valid = true;
		
		Calendar start = Calendar.getInstance();
		start.set(year, month, 1);
		Date startDate = start.getTime();
		
		Calendar end = Calendar.getInstance();
		end.set(year, month, 1);
		end.add(Calendar.MONTH, 1);
		end.add(Calendar.DATE, -1);
		Date endDate = end.getTime();
		
		System.out.println("Start: " + startDate + " | End: " + endDate);
		
		PriorityManager pm = new PriorityManager();
		PriorityDTO pr = pm.getMaxPriority();
		
		System.out.println(pr);
		
		BookingSearchDTO bs = new BookingSearchDTO();
		bs.setUserId(userId);
		bs.setStartDateFrom(startDate);
		bs.setStartDateTo(endDate);
		bs.setPriority(pr.getCode());
		
		ArrayList<String> status = new ArrayList<String>();
		status.add("Approve");
		status.add("Book");
		bs.setStatus(status);
		
		System.out.println(bs);
		
		ArrayList<BookingDTO> list = new ArrayList<BookingDTO>();
		list = findBookingByCriteria(bs);
		
		System.out.println("Size: " + list.size());
		
		if ( list.size() >= 3 && priority == pr.getCode() ) valid = false;
		
		return valid;
	}
	
	public boolean isBookingOverlap(String facility, Date start, Date end) {
		boolean valid = false;
		
		ArrayList<String> status = new ArrayList<String>();
		status.add("Approve");

		BookingSearchDTO bs = new BookingSearchDTO();
		bs.setFacilityName(facility);
		bs.setStartDateFrom(start);
		bs.setStartDateTo(end);
		bs.setEndDateFrom(start);
		bs.setEndDateTo(end);
		bs.setStatus(status);
		
		ArrayList<BookingDTO> list = findBookingByCriteria(bs);
		
		if ( list.size() > 0 ) valid = true;
		
		return valid;
	}
	
	public boolean isUserOverlap(String userId, Date start, Date end) {
		boolean valid = false;
		
		ArrayList<String> status = new ArrayList<String>();
		status.add("Approve");

		BookingSearchDTO bs = new BookingSearchDTO();
		bs.setUserId(userId);
		bs.setStartDateFrom(start);
		bs.setStartDateTo(end);
		bs.setEndDateFrom(start);
		bs.setEndDateTo(end);
		bs.setStatus(status);
		
		ArrayList<BookingDTO> list = findBookingByCriteria(bs);
		
		if ( list.size() > 0 ) valid = true;
		
		return valid;
	}

}
